package org.deltaset.samples.mvc.web;

import java.lang.reflect.Method;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.deltaset.meta.MetaAction;
import org.springframework.stereotype.Component;

/**
 *
 * @author dmakariev
 */
@Component
public class MetaActionCache {

    private final Map<String, MetaAction> cache;
    private final static String PREFIX = "ma";

    public MetaActionCache() {
        cache = new ConcurrentHashMap<String, MetaAction>();
    }

    public MetaAction getMetaActionById(String key) {
        final MetaAction metaAction = cache.get(key);
        if (null == metaAction) {
            throw new RuntimeException("no meta action for key=" + key);
        }
        return metaAction;
    }

    public String getMetaActionId(final MetaAction metaAction) {
        final String key = createKey(metaAction);
        if (false == cache.containsKey(key)) {
            cache.put(key, metaAction);
        }
        return key;
    }

    private String createKey(final MetaAction metaAction) {
        final Method method = metaAction.getMethod();

        final StringBuilder sb = new StringBuilder(PREFIX);
        sb.append(method.getDeclaringClass().getName());
        sb.append("|");
        sb.append(method.getName());
        sb.append("|");
        for (Class<?> class1 : method.getParameterTypes()) {
            sb.append(class1.getName());
            sb.append("|");
        }

        final String key = shortString(sb.toString());
        return key;
    }

    private static String shortString(final String s) {
        try {
            final MessageDigest m = MessageDigest.getInstance("MD5");
            m.update(s.getBytes(), 0, s.length());
            final String base36String = new BigInteger(1, m.digest()).toString(36);
            return base36String;
        } catch (NoSuchAlgorithmException ex) {
            throw new RuntimeException(ex);
        }
    }
}
